<?php
/**
 *+------------------
 * Lflow
 *+------------------
 * Copyright (c) 2023~2030 gitee.com/liu_guan_qing All rights reserved.本版权不可删除，侵权必究
 *+------------------
 * Author: Mr.April(405784684@qq.com)
 *+------------------
 */
declare (strict_types=1);

namespace lflow\handlers\impl;

use lflow\core\Execution;
use lflow\core\WorkFlowEngine;
use lflow\exceptions\WorkFlowException;
use lflow\handlers\IHandler;
use lflow\lib\util\StringHelper;

/**
 * 结束流程实例的处理器
 *
 * @author Mr.April
 * @since  1.0
 */
class EndProcessHandler extends \lflow\core\WorkFlowEngine implements IHandler
{

    /**
     * 结束当前流程实例，如果存在父流程，则触发父流程继续执行
     *
     * @param \lflow\core\Execution $execution
     */
    public function handle(Execution $execution): void
    {
        $engine = $execution->getEngine();
        $order  = $execution->getOrder();
        $tasks  = $engine->query()->getActiveTasks(['order_id' => $order->getData('id')]);
        foreach ($tasks['list'] as $task) {
            if (StringHelper::equalsIgnoreCase($task->task_type, 0)) {
                throw new WorkFlowException("存在未完成的主办任务,请确认.");
            }
            $engine->task()->complete($task->id, WorkFlowEngine::AUTO);
        }
        //结束当前流程实例
        $engine->order()->complete($order->getData('id'),$execution);
        //如果存在父流程，则重新构造Execution执行对象，交给父流程的SubProcessModel模型execute
        if (StringHelper::isNotEmpty($order->getData('parent_id'))) {
            $parentOrder = $engine->query()->getOrder($order->getData('parent_id'));
            if (empty($parentOrder)) return;
            $process = $engine->process()->getProcessById($parentOrder->getData('process_id'));
            $pm      = $process->getData('process_ckpt');
            if (empty($pm)) {
                return;
            }
            $spm          = $pm->getNode($order->getData('parent_node_name'));
            $newExecution = new Execution();
            $newExecution->execution($this, $process, $parentOrder, $execution->getArgs());
            $newExecution->setChildOrderId($order->getData('id'));
            $newExecution->setTask($execution->getTask());
            $spm->execute($newExecution);
            //SubProcessModel执行结果的tasks合并到当前执行对象execution的tasks列表中
            $execution->addTasks($newExecution->getTasks());
        }
    }
}
